//
//  UIImageView+WebExtras.m
//  erhuo
//
//  Created by Jingru Nie on 14/12/31.
//  Copyright (c) 2014年. All rights reserved.
//

#import "UIImageView+WebExtras.h"
#import "NSNetwork.h"
#import "NSNetCache.h"
#import "NSHash.h"
#import <sqlite3.h>

#define _CACHE_DATA_FILE @"cache.sqlite3"
#define _CACHE_DATA_TABLE @"caches"

@implementation UIImageView (WebExtras)

+ (NSString *)dataFilePath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:_CACHE_DATA_FILE];
}

+ (BOOL)execSql:(NSString *)sql with:(sqlite3 *)db
{
    char *err;
    if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) {
        sqlite3_close(db);
        NSLog(@"database operation failed!");
        return NO;
    }
    return YES;
}

+ (sqlite3 *)selectTable {
    NSString *path = [self dataFilePath];
    sqlite3 *database;
    
    if (sqlite3_open([path UTF8String], &database)!= SQLITE_OK) {
        sqlite3_close(database);
        NSLog(@"unable to open database");
        return nil;
    }
    
    NSString *createSQL = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (id INTEGER PRIMARY KEY, name TEXT, time DOUBLE);", _CACHE_DATA_TABLE];
    
    if (![self execSql:createSQL with:database]) {
        return nil;
    }
    
    return database;
}

+ (void)insertIntoSQL:(NSString *)file {
    sqlite3 *db = [self selectTable];
    if (db) {
        NSString *query = [NSString stringWithFormat:@"DELETE FROM %@ WHERE name=\"%@\"", _CACHE_DATA_TABLE, file];
        sqlite3_stmt *statement;//缓冲地带,查询完的结果,放在这个缓冲池里
        //-1是不限长度
        if (sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
            sqlite3_finalize(statement);
        }
        
        query = [NSString stringWithFormat:@"INSERT INTO %@ ('name', 'time') VALUES ('%@', '%f')", _CACHE_DATA_TABLE, file, [[NSDate date] timeIntervalSince1970]];
        if (sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
            sqlite3_finalize(statement);
        }
    }
}

+ (void)deleteCaches {
    sqlite3 *db = [self selectTable];
    if (db) {
        NSString *query = [NSString stringWithFormat:@"SELECT time FROM %@ ORDER BY time DESC LIMIT 1", _CACHE_DATA_TABLE];
        
        sqlite3_stmt *statement;
        NSTimeInterval time = 0;
        if (sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
            if (sqlite3_step(statement) == SQLITE_ROW) {
                time = (double)sqlite3_column_double(statement, 0);
                time -= 3600 * 24 * 3;
            }
            sqlite3_finalize(statement);
        }
        
        query = [NSString stringWithFormat:@"SELECT name FROM %@ WHERE time < %lf", _CACHE_DATA_TABLE, time];
        if (sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
            while (sqlite3_step(statement) == SQLITE_ROW) {
                char *rowData = (char *)sqlite3_column_text(statement, 0);
                NSNetCache *cache = [[NSNetCache alloc] initWithDirectory:@"images" FileName:[NSString stringWithUTF8String:rowData]];
                [cache deleteCache:nil];
            }
            sqlite3_finalize(statement);
        }
    }
}

- (void)setURL:(NSURL *)url cache:(NSURL *)cacheurl compress:(BOOL)compress withType:(int)type {
    UIActivityIndicatorView *acV = [[UIActivityIndicatorView alloc] initWithFrame:self.frame];
    [self addSubview:acV];
    [acV startAnimating];
    
    NSString *file = [NSHash MD5:[url absoluteString]];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSNetCache *cache = [[NSNetCache alloc] initWithDirectory:@"images" FileName:file];
        BOOL isExist = [cache cacheExist];
        __block UIImage *img;
        if (isExist == CACHEISFILE) {
            img = [UIImage imageWithContentsOfFile:[cache cachePath]];
            if (compress) {
                img = [self scaleImage:img];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                [acV stopAnimating];
                [acV removeFromSuperview];
                if (type) {
                    [self setHidden:YES];
                    [self setHighlightedImage:img];
                    [UIView animateWithDuration:0.1 animations:^{
                        [self setHidden:NO];
                    }];
                }else {
                    [self setHidden:YES];
                    [self setImage:img];
                    [UIView animateWithDuration:0.1 animations:^{
                        [self setHidden:NO];
                    }];
                }
                [UIImageView insertIntoSQL:file];
            });
        }else {
            __block BOOL ready = NO;
            __block UIImage *cacheimg;
            if (cacheurl) {
                NSString *cachefile = [NSHash MD5:[cacheurl absoluteString]];
                NSNetwork *cachenet = [[NSNetwork alloc] initWithURL:cacheurl withMethod:_NETWORK_METHOD_GET_ withData:nil withType:_NETWORK_DATA_TYPE_TEXT_];
                [cachenet sendRequest:^(NSURLResponse *response, NSData *result, NSError *error) {
                    if (!error) {
                        [cache cacheWithData:result error:nil override:YES];
                        cacheimg = [UIImage imageWithData:result];
                        [UIImageView insertIntoSQL:cachefile];
                        if (compress) {
                            cacheimg = [self scaleImage:cacheimg];
                        }
                        if (!ready) {
                            dispatch_async(dispatch_get_main_queue(), ^{
                                if (type) {
                                    [self setHidden:YES];
                                    [self setHighlightedImage:cacheimg];
                                    [UIView animateWithDuration:0.1 animations:^{
                                        [self setHidden:NO];
                                    }];
                                }else {
                                    [self setHidden:YES];
                                    [self setImage:cacheimg];
                                    [UIView animateWithDuration:0.1 animations:^{
                                        [self setHidden:NO];
                                    }];
                                }
                            });
                        }
                    }
                }];
            }
            
            
            NSNetwork *net = [[NSNetwork alloc] initWithURL:url withMethod:_NETWORK_METHOD_GET_ withData:nil withType:_NETWORK_DATA_TYPE_TEXT_];
            [net sendRequest:^(NSURLResponse *response, NSData *result, NSError *error) {
                if (error) {
                    img = [UIImage imageNamed:@"error-image"];
                }else {
                    [cache cacheWithData:result error:nil override:YES];
                    img = [UIImage imageWithData:result];
                    [UIImageView insertIntoSQL:file];
                    ready = YES;
                }
                if (compress) {
                    img = [self scaleImage:img];
                }
                dispatch_async(dispatch_get_main_queue(), ^{
                    [acV stopAnimating];
                    [acV removeFromSuperview];
                    if (type) {
                        [self setHidden:YES];
                        [self setHighlightedImage:img];
                        [UIView animateWithDuration:0.1 animations:^{
                            [self setHidden:NO];
                        }];
                    }else {
                        [self setHidden:YES];
                        [self setImage:img];
                        [UIView animateWithDuration:0.1 animations:^{
                            [self setHidden:NO];
                        }];
                    }
                });
            }];
        }
    });
}


- (void)setHighlightURL:(NSURL *)url cache:(NSURL *)cacheurl compress:(BOOL)compress {
    [self setURL:url cache:cacheurl compress:compress withType:1];
}

- (void)setImageURL:(NSURL *)url cache:(NSURL *)cacheurl compress:(BOOL)compress {
    [self setURL:url cache:cacheurl compress:compress withType:0];
}

- (void)setHighlightURL:(NSURL *)url cache:(NSURL *)cacheurl {
    [self setHighlightURL:url cache:cacheurl compress:YES];
}

- (void)setImageURL:(NSURL *)url cache:(NSURL *)cacheurl {
    [self setImageURL:url cache:cacheurl compress:YES];
}

- (void)setImageURL:(NSURL *)url compress:(BOOL)compress {
    [self setURL:url cache:nil compress:compress withType:0];
}

- (void)setHighlightURL:(NSURL *)url compress:(BOOL)compress {
    [self setURL:url cache:nil compress:compress withType:1];
}

- (void)setImageURL:(NSURL *)url {
    [self setURL:url cache:nil compress:YES withType:0];
}

- (void)setHighlightURL:(NSURL *)url {
    [self setURL:url cache:nil compress:YES withType:1];
}

- (void)setImageURL:(NSURL *)url
      highlightURL:(NSURL *)url2
{
    [self setImageURL:url];
    [self setHighlightURL:url2];
}

- (UIImage *)scaleImage:(UIImage *)image
{
    CGSize targetSize = self.bounds.size;
    CGSize sourceSize = image.size;
    CGFloat factor = 1.0f;
    CGFloat widthFactor = targetSize.width / sourceSize.width;
    CGFloat heightFactor = targetSize.height / sourceSize.height;
    
    if (self.contentMode == UIViewContentModeScaleAspectFill) {
        factor = widthFactor > heightFactor ? widthFactor : heightFactor;
    }else if (self.contentMode == UIViewContentModeScaleAspectFit) {
        factor = widthFactor < heightFactor ? widthFactor : heightFactor;
    }
    
    targetSize = CGSizeMake(sourceSize.width * factor * [[UIScreen mainScreen]scale], sourceSize.height * factor * [[UIScreen mainScreen]scale]);
    
    UIGraphicsBeginImageContext(targetSize);
    // 绘制改变大小的图片
    //[image drawInRect:CGRectMake((targetSize.width - sourceSize.width * factor) / 2, (targetSize.height - sourceSize.height * factor) / 2, sourceSize.width * factor, sourceSize.height * factor)];
    [image drawInRect:CGRectMake(0, 0, targetSize.width, targetSize.height)];
    // 从当前context中创建一个改变大小后的图片
    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    // 使当前的context出堆栈
    UIGraphicsEndImageContext();
    return scaledImage;
}

@end
